package com.xdxc.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.xdxc.response.Result;
import com.xdxc.vo.AnswerVo;
import com.xdxc.entity.CorrectAnswerVo;
import com.xdxc.mapper.QuestionMapper;
import com.xdxc.model.entity.Answer;
import com.xdxc.model.entity.CorrectAnswer;
import com.xdxc.model.entity.Question;
import com.xdxc.service.AnswerService;
import com.xdxc.service.CorrectAnswerService;
import com.xdxc.service.QuestionService;
import com.xdxc.utils.CompletableFutureUtil;
import com.xdxc.utils.ListConverter;
import com.xdxc.vo.QuestionWithOptionsVo;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.Comparator;
import java.util.List;
import java.util.Map;
import java.util.concurrent.CompletableFuture;
import java.util.stream.Collectors;

@Service
public class QuestionServiceImpl  extends ServiceImpl<QuestionMapper, Question> implements QuestionService {


    @Autowired
    private AnswerService answerService;



    @Autowired
    private CorrectAnswerService correctAnswerService;

    @Override
    public List<QuestionWithOptionsVo> getQuestionBatchByIdList(List<Long> idList, Boolean haveAnalysis){
        Map<String, Object> relationData = CompletableFutureUtil.allOf(
                () -> this.list(new LambdaQueryWrapper<Question>().in(Question::getId,idList)),
                () -> answerService.list(new LambdaQueryWrapper<Answer>().in(Answer::getQuId,idList))
                        .stream().map(answer->{
                            AnswerVo answerVo = new AnswerVo();
                            BeanUtils.copyProperties(answer,answerVo);
                            return answerVo;
                        }).sorted(Comparator.comparing(
                                AnswerVo::getSort,
                                Comparator.nullsLast(Comparator.naturalOrder())
                        )).collect(Collectors.groupingBy(AnswerVo::getQuId))
        ).join();
        List<Question> questionList =(List<Question>) relationData.get("data0");
        Map<Long, List<AnswerVo>>  answerListMap =(Map<Long, List<AnswerVo >>) relationData.get("data1");

        List<QuestionWithOptionsVo>   questionWithOptionsVoList= questionList.parallelStream().map(question -> {
            QuestionWithOptionsVo questionWithOptionsVo = new QuestionWithOptionsVo();
            BeanUtils.copyProperties(question,questionWithOptionsVo);
            questionWithOptionsVo.setAnswerVoList(answerListMap.get(question.getId()));
            if (!haveAnalysis){
                questionWithOptionsVo.setAnalysis(null);
            }
            return questionWithOptionsVo;
        }).collect(Collectors.toList());
        return questionWithOptionsVoList;
    };
    @Override
    public List<QuestionWithOptionsVo> getQuestionBatchByIdListWithCorrectAnswer(List<Long> idList){

        if (idList.size()==0){
          return   null;
        }
        Map<String, Object> relationData = CompletableFutureUtil.allOf(
                () -> this.getQuestionBatchByIdList(idList,true)

        ).join();
        List<QuestionWithOptionsVo>  questionWithOptionsVoList =( List<QuestionWithOptionsVo> ) relationData.get("data0");


        CompletableFuture<List<CorrectAnswerVo>> correctAnswerFuture = CompletableFuture.supplyAsync(() ->
                correctAnswerService.list(new LambdaQueryWrapper<CorrectAnswer>().in(CorrectAnswer::getQuestionId, idList)).stream()
                        .map(answer->{
                            CorrectAnswerVo correctAnswerVo = new CorrectAnswerVo();
                            BeanUtils.copyProperties(answer,correctAnswerVo);
                            correctAnswerVo.setOptionIds(ListConverter.convertLongToStringList(answer.getOptionIds()));
                            return correctAnswerVo;
                        })
                        .collect(Collectors.toList()));

        Map<Long,  CorrectAnswerVo> correctAnswerVoMap=correctAnswerFuture.join().stream()
                .collect(Collectors.toMap(CorrectAnswerVo::getQuestionId,correctAnswerVo -> correctAnswerVo));

        List<QuestionWithOptionsVo> question=questionWithOptionsVoList.stream().peek(questionWithOptionsVo -> {
            questionWithOptionsVo.setCorrectAnswerVo(correctAnswerVoMap.get(questionWithOptionsVo.getId()));
        }).collect(Collectors.toList());
        return question;
    };

    @Override
    public Result<List<QuestionWithOptionsVo>> questionPage(Integer page, Integer size){

        // 使用 MyBatis-Plus 的分页查询
        Page<Question> questionPage = new Page<>(page, size);
        // 使用 MyBatis-Plus 的分页查询
        IPage<Question> pagedQuestions =  this.page(questionPage);
        List<Question> questionList = pagedQuestions.getRecords();
        List<Long> idList =  questionList.stream()
                .map(Question::getId)
                .collect(Collectors.toList());
        List<QuestionWithOptionsVo> questionWithOptionsVoList=  this.getQuestionWithCorrectAnswerPage(questionList,idList);
        Result  result= Result.success(questionWithOptionsVoList);
        result.setMsg("题目获取成功");
        result.add("totalPage",pagedQuestions.getTotal());
        result.add("currentPage",pagedQuestions.getCurrent());
        result.add("pageSize",pagedQuestions.getSize());
        return result;

    };

    @Override
    public QuestionWithOptionsVo getQuestionWithOptionById(Long quId, Boolean haveAnalysis){
        Map<String, Object> relationData = CompletableFutureUtil.allOf(
                () -> this.getOne(new LambdaQueryWrapper<Question>().eq(Question::getId,quId)),
                () -> answerService.list(new LambdaQueryWrapper<Answer>().eq(Answer::getQuId,quId))
                        .stream().map(answer -> {
                            AnswerVo answerVo = new AnswerVo();
                            BeanUtils.copyProperties(answer,answerVo);
                            return answerVo;
                        }).collect(Collectors.toList())
        ).join();
        Question  question =(Question) relationData.get("data0");
        QuestionWithOptionsVo questionWithOptionsVo=new QuestionWithOptionsVo();
        BeanUtils.copyProperties(question,questionWithOptionsVo);
        List<AnswerVo>  answerList =( List<AnswerVo> ) relationData.get("data1");
        questionWithOptionsVo.setAnswerVoList(answerList);
        if (!haveAnalysis){
            questionWithOptionsVo.setAnalysis(null);
        }
        return questionWithOptionsVo;
    };





    @Override
    public QuestionWithOptionsVo getQuestionByIdWithCorrectAnswer(Long quId){
        Map<String, Object> relationData = CompletableFutureUtil.allOf(
                () -> this.getQuestionWithOptionById(quId,true),
                () -> correctAnswerService.getOne(new LambdaQueryWrapper<CorrectAnswer>().eq(CorrectAnswer::getQuestionId,quId))
        ).join();

        // 现在可以安全地使用，relationData.get("data1") 会在出错时返回 null
        QuestionWithOptionsVo questionWithOptionsVo = (QuestionWithOptionsVo) relationData.get("data0");
        CorrectAnswerVo correctAnswerVo = new CorrectAnswerVo();
        if (relationData.get("data1") != null) {
            BeanUtils.copyProperties(relationData.get("data1"), correctAnswerVo);
        }

        questionWithOptionsVo.setCorrectAnswerVo(correctAnswerVo);
        return questionWithOptionsVo;
    };
    @Override
    public List<QuestionWithOptionsVo> getQuestionWithCorrectAnswerPage(List<Question> questionList,  List<Long> idList){

        if (idList.isEmpty()) {
            return null;
        }
        CompletableFuture<Map<Long, List<AnswerVo>>> answerFuture = CompletableFuture.supplyAsync(() ->
                answerService.list(new LambdaQueryWrapper<Answer>().in(Answer::getQuId, idList)).stream()
                        .map(answer->{
                            AnswerVo answerVo = new AnswerVo();
                            BeanUtils.copyProperties(answer, answerVo); // 源对象在前
                            return answerVo;
                        })
                        .collect(Collectors.groupingBy(AnswerVo::getQuId)));
        CompletableFuture<List<CorrectAnswerVo>> correctAnswerFuture = CompletableFuture.supplyAsync(() ->
                correctAnswerService.list(new LambdaQueryWrapper<CorrectAnswer>().in(CorrectAnswer::getQuestionId, idList)).stream()
                        .map(answer->{
                            CorrectAnswerVo correctAnswerVo = new CorrectAnswerVo();
                            BeanUtils.copyProperties(answer,correctAnswerVo);
                            correctAnswerVo.setOptionIds(ListConverter.convertLongToStringList(answer.getOptionIds()));
                            return correctAnswerVo;
                        })
                        .collect(Collectors.toList()));

        Map<Long, List<AnswerVo>> userAnswersMap=answerFuture.join();
        Map<Long,  CorrectAnswerVo> correctAnswerVoMap=correctAnswerFuture.join().stream()
                .collect(Collectors.toMap(CorrectAnswerVo::getQuestionId,correctAnswerVo -> correctAnswerVo));

        List<QuestionWithOptionsVo> questionWithOptionsVoList=questionList.stream().map(question->{
            QuestionWithOptionsVo questionWithOptionsVo=new QuestionWithOptionsVo();
            BeanUtils.copyProperties(question,questionWithOptionsVo);
            questionWithOptionsVo.setAnswerVoList(userAnswersMap.get(question.getId()));
            questionWithOptionsVo.setCorrectAnswerVo(correctAnswerVoMap.get(question.getId()));
            return questionWithOptionsVo;
        }).collect(Collectors.toList());
        return questionWithOptionsVoList;
    }

























}
